package publicate;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyStore;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import protocol.Info;
import server.ServerResources;
import shamir.shamirResolver;
import data.VotesCounter;

public class Publish
{
    private static String PKWShamirPublicKeyFile;
    private static String PKWShamirPrivateKeyFile;
    private static String keyStoreFile;
    private static char[] keyStorePassword;
    static
    {
        ServerResources resources = new ServerResources();
        keyStoreFile = (String)resources.getObject( "keyStoreFile" );
        keyStorePassword = (char[])resources.getObject( "keyStorePassword" );
        PKWShamirPublicKeyFile = (String)resources.getObject( "shamirPubFile" );
        PKWShamirPrivateKeyFile = (String)resources.getObject( "shamirPrivFile" );
    }

    public static void main( String[] args )
    {
        try
        {
            System.setErr( new PrintStream( new File( "err.txt" ) ) );
            KeyStore ks = KeyStore.getInstance( KeyStore.getDefaultType() );
            FileInputStream fis = new FileInputStream( keyStoreFile );
            ks.load( fis, keyStorePassword );
            RSAPublicKey pub = (RSAPublicKey)ks.getCertificateChain( "PKW" )[ 0 ].getPublicKey();
            String[] tab = { PKWShamirPrivateKeyFile + "1.txt", PKWShamirPrivateKeyFile + "2.txt", PKWShamirPrivateKeyFile + "4.txt" };
            shamirResolver sR = new shamirResolver( tab, PKWShamirPublicKeyFile );
            RSAPrivateKey privateVotesKey = (RSAPrivateKey)sR.joinShamir();
            System.out.println( "PRZED LICZENIEM" );
            final VotesCounter counter = new VotesCounter( pub, privateVotesKey );
            counter.count();
            final String stringResult = counter.votesAsString() + "\n";
            System.out.println( stringResult );
            System.out.println( counter.showAllValidVotesHashes() );
            System.out.println( "PO LICZENIU" );
            ServerSocket ss = new ServerSocket( Info.PUBLISH_SERVER );
            while( true )
            {
                final Socket s = ss.accept();
                new Thread( new Runnable()
                {
                    public void run()
                    {
                        System.out.println( "CONNECTED" );
                        try
                        {
                            InputStream is = s.getInputStream();
                            BufferedReader in = new BufferedReader( new InputStreamReader( is ) );
                            String message = in.readLine();
                            if( message.startsWith( Info.MSG_CHECK_HASH ) )
                            {
                                message = message.substring( Info.MSG_CHECK_HASH.length() );
                                System.out.println( message );
                                boolean hasHash = counter.wasVoteCounted( message );
                                System.out.println( hasHash );
                                s.getOutputStream().write( hasHash? "true\r\n".getBytes( "UTF8" ) : "false\r\n".getBytes( "UTF8" ) );
                            }
                            else
                            {
                                s.getOutputStream().write( stringResult.getBytes( "UTF8" ) );
                                s.getOutputStream().write( "END\r\n".getBytes( "UTF8" ) );
                            }
                            Thread.sleep( 1000 );
                        }
                        catch( Exception e )
                        {
                            throw new RuntimeException( e );
                        }
                    }
                } ).start();
            }
        }
        catch( Exception e )
        {
            e.printStackTrace();
        }
    }
}
